package com.ymt.bpm.service.platform.profile.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.ymt.bpm.appboot.env.OssAvatarProperties;
import com.ymt.bpm.service.platform.profile.AvatarService;
import com.ymt.bpm.util.AES;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.EncodeUtil;
import com.ymt.bpm.util.ImageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.Map;

@Service
@EnableConfigurationProperties(value = OssAvatarProperties.class)
public class AvatarServiceImpl implements AvatarService {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OssAvatarProperties avatarProperties;

    private String commonAvatarUrlPrefix;
    private String commonAvatarPathPrefix;
    private String avatarExt = "png";

    @Override
    public JSONObject uploadAvatar(String tenantId, String loginName, Map<String, String> param, InputStream uploadIs) throws IOException {
        JSONObject rtn = new JSONObject();
        JSONObject cropData = JSONObject.parseObject(param.get("cropdata"));
        int naturalWidth = cropData.getIntValue("naturalWidth");  //get naturalWidth
        int naturalHeight = cropData.getIntValue("naturalHeight");  //get naturalHeight
        float zoomScale = cropData.getFloat("zoomScale");
        int cutX = Math.round(cropData.getIntValue("x") * zoomScale);
        int cutY = Math.round(cropData.getIntValue("y") * zoomScale);
        int cutWidth = Math.round(cropData.getIntValue("w") * zoomScale);
        int cutHeight = Math.round(cropData.getIntValue("h") * zoomScale);
        //不能越界
        if (cutWidth > naturalWidth) {
            cutWidth = naturalWidth;
        }
        if (cutHeight > naturalHeight) {
            cutHeight = naturalHeight;
        }
        if (log.isDebugEnabled()) {
            log.debug("uploadAvatar cutting and resizing image");
        }
        InputStream is = ImageUtil.cutImage(uploadIs,
                param.get("ext"), avatarExt,
                cutX, cutY, cutWidth, cutHeight, 200, 200);
        if (log.isDebugEnabled()) {
            log.debug("uploadAvatar trying uploading...");
        }
        String endpoint = avatarProperties.getSchema() + avatarProperties.getEndpoint();
        String accessKeyId = avatarProperties.getAccessKeyId();
        String accessKeySecret = avatarProperties.getAccessKeySecret();
        String bucketName = avatarProperties.getBucketName();
        String key = getAvatarPathPrefix(tenantId) + EncodeUtil.encodeBase64(loginName) + "." + avatarExt;
        ObjectMetadata meta = new ObjectMetadata();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            PutObjectResult rs = ossClient.putObject(new PutObjectRequest(bucketName, key, is, meta));
            if (log.isDebugEnabled()) {
                log.debug("uploadAvatar PutObjectResult response="+rs);
            }
            rtn.put(Const.AJAX_RESULT, true);
        } catch (OSSException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }

        return rtn;
    }

    @Override
    public String getAvatarUrlPrefix(String tenantId) {
        if (commonAvatarUrlPrefix==null) {
            commonAvatarUrlPrefix = avatarProperties.getSchema() +
                    avatarProperties.getBucketName() + "." +
                    avatarProperties.getEndpoint() + "/" +
                    getAvatarPathPrefix(tenantId);
        }
        return commonAvatarUrlPrefix;
    }

    private String getAvatarPathPrefix(String tenantId) {
        if (commonAvatarPathPrefix==null) {
            commonAvatarPathPrefix = avatarProperties.getPrefix() + "/" +
                    AES.encrypt(tenantId!=null && tenantId.length()>0 ? tenantId : "0") + "/";
        }
        return commonAvatarPathPrefix;
    }

    private void upload(String key, InputStream is, ObjectMetadata meta) throws Exception {
        String endpoint = avatarProperties.getSchema() + avatarProperties.getEndpoint();
        String accessKeyId = avatarProperties.getAccessKeyId();
        String accessKeySecret = avatarProperties.getAccessKeySecret();
        String bucketName = avatarProperties.getBucketName();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            PutObjectResult rs = ossClient.putObject(new PutObjectRequest(bucketName, key, is, meta));
            if (log.isDebugEnabled()) {
                log.debug("PutObjectResult response="+rs);
            }
        } catch (OSSException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }
    }

}
